using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.IO;


namespace Kopain
{

    /// <summary>This class represents the Settings for the application.
    /// This is like a config file but more versatile.
    /// Maybe these settings should be moved to the config file, into a branch of its own.
    /// </summary>
    class KopainSetting
    {

 #region Private properties.

        /// <summary>This is the reference to the DOM abstraction of the Setting.xml.
        /// </summary>
        private Setting _settings;

        /// <summary>This is a helper for the filename of the Settings.xml fle.
        /// </summary>
        private readonly string xmlFileName = Constant.KopainPath + @"\" + Constant.SettingXMLFileName;

        /// <summary>This is a helper for the filename of the Settings.xml schema.
        /// </summary>
        private readonly string xsdFileName = Constant.KopainPath + @"\" + Constant.SettingXSDFileName;

 #endregion  //Private properties.

 #region Public properties.

        /// <summary>There can be only one Setting file and hence we make it singleton.
        /// This is the way to make a class singleton.
        /// </summary>
        internal static readonly KopainSetting Instance = new KopainSetting();

        /// <summary>This is the getter for the XMLDOM abstraction.
        /// </summary>
        internal Setting Settings
        {
            get { return _settings; }
        }

 #endregion  //Public properties.

 #region Constructor(s).

        ///// <summary>This is a reference to the very xml document to the Setting.
        ///// </summary>
        //private XmlDocument _doc;

        /// <summary>This constructor opens the Setting file and devours its data into an XML DOM.
        /// It is private to make sure the class/object is a singleton.
        /// </summary>
        private KopainSetting()
        {
            //string xmlFileName = Constant.KopainPath + @"\" + Constant.SettingXMLFileName;
            //string xsdFileName = Constant.KopainPath + @"\" + Constant.SettingXSDFileName;


            //  Validate the document.
            //
            XmlDocument docTemp = new XmlDocument();
            try
            {
                docTemp.Load( xmlFileName );
                docTemp.Schemas.Add( null, xsdFileName );
                docTemp.Validate( null );

                //  Deserialize the file so we can have our settings.
                //
                XmlSerializer serz = new XmlSerializer( typeof( Setting ) );
                using( FileStream filestream = new FileStream( xmlFileName, FileMode.Open ) )
                {
                    _settings = (Setting)serz.Deserialize( filestream );
                    filestream.Close();
                }
            }
            catch( XmlException exc )
            {
                throw new Exception.CorruptSettingsFile( exc );
            }

        }

 #endregion  //Constructor(s).

 #region Public methods.

        /// <summary>This method serializes the settings and saves them in Setting.xml.
        /// </summary>
        internal void Save()
        {
            XmlSerializer serz = new XmlSerializer( typeof( Setting ) );
            using( StreamWriter writer = new StreamWriter( xmlFileName ) )
            {
                serz.Serialize( writer, _settings );
                writer.Close();
            }
        }

 #endregion  // Publid methods.
        
    }
}